const puppeteer = require('puppeteer-core');
const { chromium } = require('playwright-core');
const config = require('../config/config');
const { logger } = require('../utils/logger');

class Browser {
  constructor() {
    this.puppeteerBrowsers = [];
    this.playwrightBrowsers = [];
    this.availablePuppeteerBrowsers = [];
    this.availablePlaywrightBrowsers = [];
    this.isInitialized = false;
  }

  async init() {
    if (this.isInitialized) return;
    
    logger.info(`初始化浏览器池，Puppeteer实例数: ${config.browser.maxInstances}`);
    
    // 初始化Puppeteer浏览器
    for (let i = 0; i < config.browser.maxInstances; i++) {
      try {
        // 添加重试机制
        let browser = null;
        let retryCount = 0;
        const maxRetries = 3;
        
        while (retryCount < maxRetries && !browser) {
          try {
            browser = await puppeteer.launch({
              ...config.browser.launchOptions,
              timeout: 30000 // 30秒超时
            });
            
            // 验证浏览器是否正常工作
            const testPage = await browser.newPage();
            await testPage.close();
            
            this.puppeteerBrowsers.push(browser);
            this.availablePuppeteerBrowsers.push(browser);
            logger.info(`Puppeteer浏览器实例 ${i + 1} 创建成功`);
            break;
          } catch (launchError) {
            retryCount++;
            logger.warn(`Puppeteer浏览器实例 ${i + 1} 创建失败 (尝试 ${retryCount}/${maxRetries}): ${launchError.message}`);
            
            if (retryCount >= maxRetries) {
              logger.error(`Puppeteer浏览器实例 ${i + 1} 创建最终失败: ${launchError.message}`);
            } else {
              await this.wait(2000); // 等待2秒后重试
            }
          }
        }
      } catch (error) {
        logger.error(`创建Puppeteer浏览器失败: ${error.message}`);
      }
    }

    // 初始化Playwright浏览器
    for (let i = 0; i < config.browser.maxInstances; i++) {
      try {
        const browser = await chromium.launch(config.browser.playwrightOptions || {
          headless: true
        });
        this.playwrightBrowsers.push(browser);
        this.availablePlaywrightBrowsers.push(browser);
        logger.info(`Playwright浏览器实例 ${i + 1} 创建成功`);
      } catch (error) {
        logger.error(`创建Playwright浏览器失败: ${error.message}`);
      }
    }
    
    this.isInitialized = true;
  }

  async getPuppeteerBrowser() {
    if (this.availablePuppeteerBrowsers.length === 0) {
      throw new Error('没有可用的Puppeteer浏览器实例');
    }
    return this.availablePuppeteerBrowsers.pop();
  }

  async getPlaywrightBrowser() {
    if (this.availablePlaywrightBrowsers.length === 0) {
      throw new Error('没有可用的Playwright浏览器实例');
    }
    return this.availablePlaywrightBrowsers.pop();
  }

  releasePuppeteerBrowser(browser) {
    if (browser && browser.isConnected()) {
      this.availablePuppeteerBrowsers.push(browser);
    }
  }

  releasePlaywrightBrowser(browser) {
    if (browser && browser.isConnected()) {
      this.availablePlaywrightBrowsers.push(browser);
    }
  }

  // 通用的等待函数
  async wait(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }

  // Puppeteer运行方法
  async runWithPuppeteer(url, options = {}, operation) {
    let browser = null;
    let page = null;
    
    try {
      browser = await this.getPuppeteerBrowser();
      
      // 验证浏览器连接状态
      if (!browser.isConnected()) {
        throw new Error('浏览器连接已断开');
      }
      
      page = await browser.newPage();
      
      // 设置视口
      await page.setViewport({
        width: options.width || 1280,
        height: options.height || 720
      });
      
      // 设置页面超时
      page.setDefaultTimeout(config.browser.pageTimeout);
      page.setDefaultNavigationTimeout(config.browser.pageTimeout);
      
      // 导航到页面
      await page.goto(url, {
        waitUntil: options.waitUntil || 'domcontentloaded',
        timeout: config.browser.pageTimeout
      });
      
      // 等待额外时间
      if (options.delay) {
        await this.wait(options.delay);
      }
      
      // 执行操作
      return await operation(page, options);
      
    } catch (error) {
      logger.error(`Puppeteer操作失败: ${error.message}`);
      
      // 如果是连接错误，尝试重新初始化浏览器
      if (error.message.includes('Connection closed') || error.message.includes('Protocol error')) {
        logger.warn('检测到浏览器连接问题，尝试重新初始化...');
        await this.destroy();
        await this.init();
      }
      
      throw error;
    } finally {
      if (page) {
        try {
          await page.close();
        } catch (closeError) {
          logger.warn(`关闭页面失败: ${closeError.message}`);
        }
      }
      if (browser) {
        this.releasePuppeteerBrowser(browser);
      }
    }
  }

  // Playwright运行方法
  async runWithPlaywright(url, options = {}, operation) {
    let browser = null;
    let page = null;
    
    try {
      browser = await this.getPlaywrightBrowser();
      page = await browser.newPage();
      
      // 设置视口
      await page.setViewportSize({
        width: options.width || 1280,
        height: options.height || 720
      });
      
      // 导航到页面
      await page.goto(url, {
        waitUntil: options.waitUntil || 'networkidle',
        timeout: config.browser.pageTimeout
      });
      
      // 等待额外时间
      if (options.delay) {
        await page.waitForTimeout(options.delay);
      }
      
      // 执行操作
      return await operation(page, options);
      
    } catch (error) {
      logger.error(`Playwright操作失败: ${error.message}`);
      throw error;
    } finally {
      if (page) {
        await page.close().catch(() => {});
      }
      if (browser) {
        this.releasePlaywrightBrowser(browser);
      }
    }
  }

  // 兼容性方法，默认使用Puppeteer
  async run(url, options = {}, operation) {
    return this.runWithPuppeteer(url, options, operation);
  }

  async destroy() {
    // 销毁Puppeteer浏览器
    for (const browser of this.puppeteerBrowsers) {
      if (browser.isConnected()) {
        await browser.close();
      }
    }
    this.puppeteerBrowsers = [];
    this.availablePuppeteerBrowsers = [];

    // 销毁Playwright浏览器
    for (const browser of this.playwrightBrowsers) {
      if (browser.isConnected()) {
        await browser.close();
      }
    }
    this.playwrightBrowsers = [];
    this.availablePlaywrightBrowsers = [];
    
    this.isInitialized = false;
  }

  // 获取状态信息
  getStatus() {
    return {
      puppeteer: {
        total: this.puppeteerBrowsers.length,
        available: this.availablePuppeteerBrowsers.length
      },
      playwright: {
        total: this.playwrightBrowsers.length,
        available: this.availablePlaywrightBrowsers.length
      },
      isInitialized: this.isInitialized
    };
  }
}

// 单例
const browser = new Browser();
module.exports = browser;
